本篇說明 django 使用資料庫的方式
以及應用面會使用到的多資料庫設置
本篇沒有說明關聯表的操作方式,後續系列會在深入研究
# app(testSetting) > models.py
from django.db import models
# 以下為一個一對多的關係,一個問題可以有很多個答案
# 問題
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    class Meta:
        db_table = 'question'   # 指定資料庫名稱,否則預設為appName + 表名稱 > ex: testSetting_question
# 答案
class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    class Meta:
        db_table = 'choice'     # 資料庫名稱
基本上會遇到兩種情況
於 CMD 視窗執行
py manage.py makemigrations
於各個App內的
migrations資料夾會出現該次更新的內容
注意!!! 目前執行到這還尚未被資料庫應用,所以在資料庫中並不會看見資料表本次新增的內容
0001_initial.py,主要為創建資料表內容的代碼
於 CMD 視窗執行
python manage.py migrate testSetting
執行成功後於DB即可看到建置資料表,使用此命令,資料表名稱會預設為appName + tableName,如下

# views.py
# 新增
def addApi(request):
    q = Question(question_text="臉有什麼器官?", pub_date=timezone.now())
    q.save() # save(commit)才會實際執行
    rep = {
        'msg': 'add一筆資料'
    }
    return JsonResponse(rep)
# 取得
def getApi(request):
    data = Question.objects.all() # 取全部
    # data = Question.objects.get() # 只取一筆
    # data = Question.objects.filter(question_text = '條件') # 過濾條件
    # 通常在使用上我會轉為陣列字典形式,在使用以及回傳json轉換上都比較方便
    rep = {
        'msg': list(data.values())
    }
    return JsonResponse(rep)
# 修改
def updateApi(request):
    data = Question.objects.filter(question_text="臉有什麼器官?") # 取得需要修改的資料
    data.update(question_text = '身體有什麼器官?')
    rep = {
        'msg': '修改一筆資料'
    }
    return JsonResponse(rep)
# 刪除
def deleteApi(request):
    data = Question.objects.filter(question_text="身體有什麼器官?") # 取得需要刪除的資料
    data.delete()
    rep = {
        'msg': '刪除一筆資料'
    }
    return JsonResponse(rep)
# 路由定義
from django.urls import path
from . import views
urlpatterns = [
    path('firstApi', views.firstApi, name = 'firstApi'),
    path('addApi', views.addApi, name = 'addApi'),
    path('getApi', views.getApi, name = 'getApi'),
    path('updateApi', views.updateApi, name = 'updateApi'),
    path('deleteApi', views.deleteApi, name = 'deleteApi')
]
基本上一個資料庫要擁有所有東西是不太可能的,
有時候可能是因為部門、資料量、分類等等因素。
# 這邊要新增一隻檔案
# 於專案目錄下新增 database_router.py
# 內容大致上就是將增修改查指定的資料庫配對到我們所需的位置
from django.conf import settings
DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING
class DatabaseAppsRouter(object):
    """
    A router to control all database operations on models for different
    databases.
    In case an app is not set in settings.DATABASE_APPS_MAPPING, the router
    will fallback to the `default` database.
    Settings example:
    DATABASE_APPS_MAPPING = {'app1': 'db1', 'app2': 'db2'}
    """
    def db_for_read(self, model, **hints):
        """"Point all read operations to the specific database."""
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None
    def db_for_write(self, model, **hints):
        """Point all write operations to the specific database."""
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None
    def allow_relation(self, obj1, obj2, **hints):
        """Allow any relation between apps that use the same database."""
        db_obj1 = DATABASE_MAPPING.get(obj1._meta.app_label)
        db_obj2 = DATABASE_MAPPING.get(obj2._meta.app_label)
        if db_obj1 and db_obj2:
            if db_obj1 == db_obj2:
                return True
            else:
                return False
        return None
    def allow_syncdb(self, db, model):
        """Make sure that apps only appear in the related database."""
        if db in DATABASE_MAPPING.values():
            return DATABASE_MAPPING.get(model._meta.app_label) == db
        elif model._meta.app_label in DATABASE_MAPPING:
            return False
        return None
    def allow_migrate(self, db, app_label, model=None, **hints):
        """
        Make sure the auth app only appears in the 'auth_db'
        database.
        """
        if db in DATABASE_MAPPING.values():
            return DATABASE_MAPPING.get(app_label) == db
        elif app_label in DATABASE_MAPPING:
            return False
        return None
# project settings
# 指定路由 > 為剛剛設置的檔案
# DATABASE_ROUTERS = ['專案名稱.檔案名稱.功能名稱']
DATABASE_ROUTERS = ['djangoAPI.database_router.DatabaseAppsRouter']
# 接下來就是設定的部份,預先會定義一個default,當沒指定時就使用該DB
# 其餘部份就看使用的資料庫引擎及定義名稱、帳號、密碼等等
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
    'db2': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db2.sqlite3'),
    }
}
# 路由配對
DATABASE_APPS_MAPPING = {
    'db2': 'db2'
}
如此一來就設定好路由了,但注意該部份因為設置了路由,
所以各個部份都需要指定database給django,否則會出現一些錯誤
例如剛剛上述有提到的python manage.py migrate --database=dbName這部份就需要指定資料庫名稱
詳細了解可以看官方文檔
from django.db import models
# 問題
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    class Meta:
        app_label = 'db2'   # setting DATABASE_APPS_MAPPING 配對名稱
        db_table = 'db2_question'
# app.urls
from django.urls import path
from . import views
urlpatterns = [
    path('get_Db2_Api', views.get_Db2_Api, name = 'get_Db2_Api')
]
實際使用與單個DB相同
以上就完成了實際應用會出現的多資料庫的應用,在增修改查的使用上與酖個資料庫相同,只要在模型中的Meta中設置完成就沒問題了。